Service Container的觀念滿抽象的,以下是其觀念:
Laravel 的 Service Container(服務容器)是框架中一個關鍵的功能,它是一種依賴注入(Dependency Injection)和服務解析(Service Resolution)的容器。它有助於簡化依賴注入、服務解析和管理相依性的過程,使您能夠更輕鬆地構建可維護和可測試的應用程序 - ChatGPT
上一篇使用的
public function index(PostService $postService) {
    ...
}
PostService $postService 就是使用Service Container
當然也可以不只注入一個,如:
public function index(PostService $postService, Request $request) {
    ...
}
提供綁定功能,綁定甚麼?
在注入的時候,決定該綁定到哪個Class
接著看吧
今天筆者想用這部影片
結合我們之前所使用的Post功能,增加限時貼文(expired_at)
今天沿用前面使用的Post表,新增type、expired_at
database\migrations\2023_09_19_164215_create_posts_table.php
public function up(): void
{
    Schema::create('posts', function (Blueprint $table) {
        $table->id();
        $table->bigInteger('user_id')->default(0)->comment('關聯使用者')->index();
        $table->text('title');
        $table->text('content');
        $table->integer('views')->default(0)->comment('觀看數');
        $table->string('type', '20')->nullable();
        $table->timestamp('expired_at')->nullable();
        $table->timestamps();
        $table->softDeletes();
    });
}
在終端跑php artisan migrate:rollback && php artisan migrate

手動建立PostRepositoryInterface
app\Interfaces\PostRepositoryInterface.php
<?php
namespace App\Interfaces;
interface PostRepositoryInterface
{
    public function get();
    public function create(array $data): void;
}
app\Repositories\PostRepository.php
<?php 
namespace App\Repositories;
use App\Interfaces\PostRepositoryInterface;
use App\Models\Post;
use Illuminate\Database\Eloquent\Collection;
class PostRepository implements PostRepositoryInterface
{
    public function get(): Collection
    {
        return Post::where('type', 'post')
        ->orderBy('id', 'desc')
        ->get();
    }
    public function create($data): void
    {
        $data['type'] = 'post';
        Post::create($data);
    }
}
app\Repositories\StoryRepository.php
<?php 
namespace App\Repositories;
use App\Interfaces\PostRepositoryInterface;
use App\Models\Post;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
class StoryRepository implements PostRepositoryInterface
{
    public function get(): Collection
    {
        return Post::where('expired_at', '>', Carbon::now())
        ->where('type', 'story')
        ->orderBy('id', 'desc')
        ->get();
    }
    public function create($data): void
    {
        $data['expired_at'] = Carbon::now()->addDay();
        $data['type'] = 'story';
        Post::create($data);
    }
}
php artisan make:provider PostServiceProvider
app\Providers\PostServiceProvider.php
<?php
namespace App\Providers;
use App\Interfaces\PostRepositoryInterface;
use App\Repositories\PostRepository;
use App\Repositories\StoryRepository;
use Illuminate\Support\ServiceProvider;
class PostServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     */
    public function register(): void
    {
        $this->app->bind(PostRepositoryInterface::class, function ($app){
            if (request()->input('type') === 'story'){
                return new StoryRepository();
            } else {
                return new PostRepository();
                // default is normal post
            }
        });
    }
    /**
     * Bootstrap services.
     */
    public function boot(): void
    {
        //
    }
}
config\app.php 加入 App\Providers\PostServiceProvider::class,
新增post
取得post
新增story
取得story
本篇簡單有實際例子演示如何使用Service Provider,註冊PostRepository到Service Container中
並在Service Provider作了一些判斷來演示其中的發展性
如以下幾個例子,比較生活化能應用的到:
銀行、各第三方訊息API(Line、Telegram、Discord...)、File Cloud(AWS、GCP...)
如果想多了解的話建議可以看開頭的影片,那我們下篇見~
如何理解 Laravel 的 IoC 容器
Laravel 6 Advanced - e1 - Service Container